/**
 * Spark创作状态管理Provider
 */

import React, {
  createContext,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState
} from 'react'
import type { ReactNode } from 'react'

// 服务导入
import { AIService } from '../../../services/ai/aiService'
import { SparkCreationService } from '../../../services/ai/sparkCreationService'
import { getAIConfig } from '../../../services/ai/config'

// 工具函数导入
import { markdownToHtml } from '../../utils/exportUtils'

// 类型导入
import {
  SparkCreationData,
  SparkDialogState,
  ArticleOutline,
  ContentGenerationState,
  DialogStep,
  OutlineSection,
  SectionStatus,
  createDefaultSparkCreationData,
  getNextPendingSection as getNextPendingSectionUtil
} from '../../../types/spark'
import { AIError } from '../../../services/ai/types'
import {
  SparkCreationViewState,
  SparkCreationActions,
  SparkCreationContextValue,
  SparkCreationConfig
} from './types'

// 辅助函数导入
import {
  createInitialSparkState,
  updateSectionInOutline,
  updateGenerationProgress,
  isOutlineFullyGenerated,
  mergeFullArticle,
  validateSparkSession,
  cleanupSessionCache
} from './helpers'

// 存储键定义
const STORAGE_KEYS = {
  RECENT_SESSIONS: 'rmzf:spark:recent_sessions',
  CURRENT_SESSION: 'rmzf:spark:current_session'
}

export interface SparkCreationProviderProps {
  children: ReactNode
  onContentGenerated?: (content: string) => void
  onTitleGenerated?: (title: string) => void
}

export const SparkCreationContext = createContext<SparkCreationContextValue | undefined>(
  undefined
)

const SparkCreationProvider: React.FC<SparkCreationProviderProps> = ({
  children,
  onContentGenerated,
  onTitleGenerated
}) => {
  // 状态定义
  const [state, setState] = useState<SparkCreationViewState>(createInitialSparkState())
  
  // 服务实例
  const [sparkService, setSparkService] = useState<SparkCreationService | null>(null)
  
  // 初始化标志
  const initializedRef = useRef(false)

  // 初始化AI服务
  useEffect(() => {
    const initializeService = async () => {
      try {
        const aiConfig = await getAIConfig()
        if (!aiConfig || !aiConfig.apiKey) {
          console.warn('[Spark状态] AI API密钥未配置')
          return
        }

        const aiService = new AIService({
          openaiApiKey: aiConfig.apiKey,
          baseURL: aiConfig.apiBaseUrl || undefined,
          model: aiConfig.model || 'gpt-3.5-turbo'
        })

        const service = new SparkCreationService(aiService)
        setSparkService(service)
        
        console.log('[Spark状态] AI服务初始化完成')
      } catch (error) {
        console.error('[Spark状态] AI服务初始化失败:', error)
        setState(prev => ({
          ...prev,
          error: {
            code: 'API_KEY_MISSING' as any,
            message: 'AI服务初始化失败，请检查配置'
          }
        }))
      }
    }

    if (!initializedRef.current) {
      initializedRef.current = true
      initializeService()
      loadRecentSessions()
    }
  }, [])

  // 开始Spark创作
  const startSpark = useCallback(async (sparkInput: string) => {
    if (!sparkService) {
      setState(prev => ({
        ...prev,
        error: { code: 'API_KEY_MISSING' as any, message: 'AI服务未初始化' }
      }))
      return
    }

    setState(prev => ({ ...prev, isLoading: true, error: null }))

    try {
      console.log('[Spark状态] 开始创作流程', { sparkInput })
      
      // 创建新会话
      const newSession = createDefaultSparkCreationData(sparkInput)
      
      // 启动对话流程
      const result = await sparkService.startSparkCreation(sparkInput)
      
      if (!result.ok) {
        throw result.error
      }

      setState(prev => ({
        ...prev,
        currentSession: newSession,
        currentDialogStep: result.data,
        isDialogOpen: true,
        isLoading: false
      }))

    } catch (error) {
      console.error('[Spark状态] 启动创作失败:', error)
      setState(prev => ({
        ...prev,
        error: error as AIError,
        isLoading: false
      }))
    }
  }, [sparkService])

  // 继续对话
  const continueDialog = useCallback(async (response: string) => {
    if (!sparkService || !state.currentSession) {
      return
    }

    setState(prev => ({ ...prev, isLoading: true, error: null }))

    try {
      console.log('[Spark状态] 继续对话', { response })

      const result = await sparkService.processUserResponse(
        state.currentSession.dialogState,
        response
      )

      if (!result.ok) {
        throw result.error
      }

      // 使用Service返回的完整对话状态
      const { dialogState: updatedDialogState, nextStep } = result.data

      // 更新会话状态
      const updatedSession = {
        ...state.currentSession,
        dialogState: updatedDialogState,  // 使用Service返回的完整状态（包含用户回答）
        updatedAt: new Date()
      }

      console.log('[Spark状态] 会话状态已更新', {
        currentStep: updatedDialogState.currentStep,
        isCompleted: updatedDialogState.isCompleted,
        responses: updatedDialogState.responses
      })

      if (nextStep) {
        // 还有下一步对话
        setState(prev => ({
          ...prev,
          currentSession: updatedSession,
          currentDialogStep: nextStep,
          isLoading: false
        }))
      } else {
        // 对话完成，保持在对话界面但进入加载状态
        // 不要设置currentDialogStep为null，保持最后一个步骤显示加载界面
        setState(prev => ({
          ...prev,
          currentSession: updatedSession,
          // 保持currentDialogStep，让DialogInterface显示加载状态
          isLoading: true
        }))

        console.log('[Spark状态] 对话完成，开始生成大纲')

        // 自动生成大纲（使用更新后的session）
        await generateOutlineWithState(updatedSession)
      }

    } catch (error) {
      console.error('[Spark状态] 对话继续失败:', error)
      setState(prev => ({
        ...prev,
        error: error as AIError,
        isLoading: false
      }))
    }
  }, [sparkService, state.currentSession])

  // 生成大纲（使用指定的session）
  const generateOutlineWithState = async (session: SparkCreationData) => {
    if (!sparkService) {
      return
    }

    // 注意：此时isLoading已经在continueDialog中设置为true了

    try {
      console.log('[Spark状态] 生成大纲', {
        sessionId: session.id,
        dialogState: session.dialogState
      })

      const result = await sparkService.generateOutline(session.dialogState)

      if (!result.ok) {
        throw result.error
      }

      console.log('[Spark状态] 大纲生成成功', { outline: result.data })

      const updatedSession = {
        ...session,
        outline: result.data,
        status: 'generating' as const,
        updatedAt: new Date()
      }

      setState(prev => ({
        ...prev,
        currentSession: updatedSession,
        currentOutline: result.data,
        currentDialogStep: null,  // 现在可以安全地清除dialogStep了
        isLoading: false
      }))

      // 保存会话
      await saveCurrentSession(updatedSession)

    } catch (error) {
      console.error('[Spark状态] 大纲生成失败:', error)
      setState(prev => ({
        ...prev,
        error: error as AIError,
        isLoading: false
      }))
    }
  }

  // 生成大纲
  const generateOutline = useCallback(async () => {
    if (!sparkService || !state.currentSession) {
      return
    }

    setState(prev => ({ ...prev, isLoading: true, error: null }))

    try {
      console.log('[Spark状态] 生成大纲')
      
      const result = await sparkService.generateOutline(state.currentSession.dialogState)
      
      if (!result.ok) {
        throw result.error
      }

      const updatedSession = {
        ...state.currentSession,
        outline: result.data,
        status: 'generating' as const,
        updatedAt: new Date()
      }

      setState(prev => ({
        ...prev,
        currentSession: updatedSession,
        currentOutline: result.data,
        isLoading: false
      }))

      // 保存会话
      await saveCurrentSession(updatedSession)

    } catch (error) {
      console.error('[Spark状态] 大纲生成失败:', error)
      setState(prev => ({
        ...prev,
        error: error as AIError,
        isLoading: false
      }))
    }
  }, [sparkService, state.currentSession])

  // 生成段落内容
  const generateSectionContent = useCallback(async (sectionId: string) => {
    if (!sparkService || !state.currentOutline) {
      return
    }

    setState(prev => ({ ...prev, isGenerating: true, error: null }))

    try {
      console.log('[Spark状态] 生成段落内容', { sectionId })

      const section = state.currentOutline.sections.find(s => s.id === sectionId)
      if (!section) {
        throw new Error('段落不存在')
      }

      // 更新段落状态为生成中
      const updatedOutline = updateSectionInOutline(state.currentOutline, sectionId, {
        status: SectionStatus.GENERATING
      })

      setState(prev => ({
        ...prev,
        currentOutline: updatedOutline,
        generationState: {
          ...prev.generationState,
          currentSectionIndex: updatedOutline.sections.findIndex(s => s.id === sectionId)
        }
      }))

      // 获取前文内容
      const previousContent = mergeFullArticle({
        ...updatedOutline,
        sections: updatedOutline.sections.filter(s =>
          s.order < section.order && s.status === SectionStatus.COMPLETED
        )
      })

      // 创建超时Promise (30秒)
      const timeoutPromise = new Promise<never>((_, reject) => {
        setTimeout(() => {
          reject(new Error('生成超时（30秒）'))
        }, 30000)
      })

      // 使用Promise.race实现超时检测
      const result = await Promise.race([
        sparkService.generateSectionContent(
          section,
          updatedOutline,
          previousContent
        ),
        timeoutPromise
      ])

      if (!result.ok) {
        throw result.error
      }

      // 更新段落内容
      const finalOutline = updateSectionInOutline(updatedOutline, sectionId, {
        content: result.data,
        status: SectionStatus.COMPLETED
      })

      // 更新生成进度
      const updatedGenerationState = updateGenerationProgress(
        state.generationState,
        finalOutline
      )

      setState(prev => ({
        ...prev,
        currentOutline: finalOutline,
        generationState: updatedGenerationState,
        isGenerating: false
      }))

      // 检查是否全部完成
      if (isOutlineFullyGenerated(finalOutline)) {
        const fullContent = mergeFullArticle(finalOutline)

        // 将Markdown转换为HTML
        const htmlContent = markdownToHtml(fullContent)

        // 生成文章标题
        console.log('[Spark状态] 开始生成文章标题')
        try {
          const titleResult = await sparkService.generateArticleTitle(
            fullContent,
            state.currentSession!.dialogState
          )

          if (titleResult.ok && titleResult.data) {
            console.log('[Spark状态] 标题生成成功:', titleResult.data)
            // 通过回调传递标题
            onTitleGenerated?.(titleResult.data)
          } else {
            console.warn('[Spark状态] 标题生成失败，使用默认标题')
          }
        } catch (titleError) {
          console.error('[Spark状态] 标题生成出错:', titleError)
        }

        // 更新会话状态
        const completedSession = {
          ...state.currentSession!,
          outline: finalOutline,
          finalContent: fullContent,  // 保存原始markdown
          status: 'completed' as const,
          updatedAt: new Date()
        }

        setState(prev => ({
          ...prev,
          currentSession: completedSession
        }))

        // 导出HTML格式到编辑器
        onContentGenerated?.(htmlContent)

        // 保存会话
        await saveCurrentSession(completedSession)
      }

    } catch (error) {
      console.error('[Spark状态] 段落生成失败:', error)
      
      // 恢复段落状态
      if (state.currentOutline) {
        const revertedOutline = updateSectionInOutline(state.currentOutline, sectionId, {
          status: SectionStatus.ERROR
        })
        
        setState(prev => ({
          ...prev,
          currentOutline: revertedOutline,
          error: error as AIError,
          isGenerating: false
        }))
      }
    }
  }, [sparkService, state.currentOutline, state.currentSession, state.generationState, onContentGenerated])

  // 重新生成段落内容
  const regenerateSectionContent = useCallback(async (sectionId: string) => {
    if (!state.currentOutline) return

    // 重置段落状态
    const resetOutline = updateSectionInOutline(state.currentOutline, sectionId, {
      content: undefined,
      status: SectionStatus.PENDING
    })

    setState(prev => ({
      ...prev,
      currentOutline: resetOutline
    }))

    // 重新生成
    await generateSectionContent(sectionId)
  }, [state.currentOutline, generateSectionContent])

  // 生成完整文章
  const generateFullArticle = useCallback(async () => {
    if (!state.currentOutline) return

    // 按顺序生成每个段落
    const pendingSections = state.currentOutline.sections
      .filter(section => section.status === SectionStatus.PENDING)
      .sort((a, b) => a.order - b.order)

    for (const section of pendingSections) {
      await generateSectionContent(section.id)
    }
  }, [state.currentOutline, generateSectionContent])

  // 保存当前会话
  const saveCurrentSession = useCallback(async (session?: SparkCreationData) => {
    const sessionToSave = session || state.currentSession
    if (!sessionToSave) return

    try {
      // 保存到localStorage
      localStorage.setItem(STORAGE_KEYS.CURRENT_SESSION, JSON.stringify(sessionToSave))
      
      // 更新最近会话列表
      const recentSessions = state.recentSessions.filter(s => s.id !== sessionToSave.id)
      recentSessions.unshift(sessionToSave)
      const cleanedSessions = cleanupSessionCache(recentSessions)
      
      localStorage.setItem(STORAGE_KEYS.RECENT_SESSIONS, JSON.stringify(cleanedSessions))
      
      setState(prev => ({
        ...prev,
        recentSessions: cleanedSessions
      }))

      console.log('[Spark状态] 会话已保存', { sessionId: sessionToSave.id })

    } catch (error) {
      console.error('[Spark状态] 保存会话失败:', error)
    }
  }, [state.currentSession, state.recentSessions])

  // 加载最近会话
  const loadRecentSessions = useCallback(async () => {
    try {
      const stored = localStorage.getItem(STORAGE_KEYS.RECENT_SESSIONS)
      if (stored) {
        const sessions = JSON.parse(stored)
        setState(prev => ({
          ...prev,
          recentSessions: sessions
        }))
      }
    } catch (error) {
      console.error('[Spark状态] 加载最近会话失败:', error)
    }
  }, [])

  // UI控制方法
  const openDialog = useCallback(() => {
    setState(prev => ({ ...prev, isDialogOpen: true }))
  }, [])

  const closeDialog = useCallback(() => {
    setState(prev => ({ ...prev, isDialogOpen: false }))
  }, [])

  const resetDialog = useCallback(() => {
    setState(createInitialSparkState())
  }, [])

  const clearError = useCallback(() => {
    setState(prev => ({ ...prev, error: null }))
  }, [])

  // 其他操作方法（占位实现）
  const updateOutline = useCallback((outline: ArticleOutline) => {
    setState(prev => ({
      ...prev,
      currentOutline: outline,
      currentSession: prev.currentSession ? {
        ...prev.currentSession,
        outline,
        updatedAt: new Date()
      } : null
    }))
  }, [])

  const updateSection = useCallback((sectionId: string, updates: Partial<OutlineSection>) => {
    if (!state.currentOutline) return

    const updatedOutline = updateSectionInOutline(state.currentOutline, sectionId, updates)
    updateOutline(updatedOutline)
  }, [state.currentOutline, updateOutline])

  const loadSession = useCallback(async (sessionId: string) => {
    // TODO: 实现会话加载
    console.log('[Spark状态] 加载会话', { sessionId })
  }, [])

  const deleteSession = useCallback(async (sessionId: string) => {
    setState(prev => ({
      ...prev,
      recentSessions: prev.recentSessions.filter(s => s.id !== sessionId)
    }))
  }, [])

  const listRecentSessions = useCallback(async () => {
    await loadRecentSessions()
  }, [loadRecentSessions])

  const exportToEditor = useCallback((content: string) => {
    onContentGenerated?.(content)
  }, [onContentGenerated])

  // 组装actions对象
  const actions = useMemo<SparkCreationActions>(() => ({
    startSpark,
    continueDialog,
    resetDialog,
    generateOutline,
    updateOutline,
    updateSection,
    generateSectionContent,
    regenerateSectionContent,
    generateFullArticle,
    saveSession: () => saveCurrentSession(),
    loadSession,
    deleteSession,
    listRecentSessions,
    openDialog,
    closeDialog,
    clearError,
    exportToEditor
  }), [
    startSpark,
    continueDialog,
    resetDialog,
    generateOutline,
    updateOutline,
    updateSection,
    generateSectionContent,
    regenerateSectionContent,
    generateFullArticle,
    saveCurrentSession,
    loadSession,
    deleteSession,
    listRecentSessions,
    openDialog,
    closeDialog,
    clearError,
    exportToEditor
  ])

  // 组装context值
  const contextValue = useMemo<SparkCreationContextValue>(() => ({
    state,
    actions
  }), [state, actions])

  return (
    <SparkCreationContext.Provider value={contextValue}>
      {children}
    </SparkCreationContext.Provider>
  )
}

export default SparkCreationProvider